/*
 *  Copyright 2020-2025 the original author or authors.
 *  You cannot use this file unless authorized by the author.
 */

package org.ipig.commons.helper;

import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import org.apache.commons.lang.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ChineseHelper
 *
 * @author <a href="mailto:comchnts@163.com">chinats</a>
 * @version $$Id: ChineseHelper.java 16 2020-04-30 09:35:40Z ts <comchnts@163.com> $$
 * @since 1.0
 */
@Slf4j
public class ChineseHelper {
    /**
     * 字符串转Unicode
     *
     * @param str
     * @return abbr
     */
    public static String toPinyin(String str, String separate, boolean retain) {
        StringBuilder sb = new StringBuilder();
        //创建汉语拼音处理类
        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        // 输出设置，大小写，音标方式
        defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        try {
            String newStr = PinyinHelper.toHanYuPinyinString(str, defaultFormat, separate, retain);
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error(ex.getMessage());
        }
        return sb.toString();
    }

    /**
     * 字符串转Unicode
     *
     * @param str
     * @return
     */
    public static String toUnicode(String str) {
        return toUnicode(str, null);
    }

    /**
     * 字符串转Unicode
     *
     * @param str
     * @return
     */
    public static String toUnicode(String str, String separate) {
        if (StringUtils.isBlank(str)) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        String newSeparate = StringUtils.EMPTY;
        if (StringUtils.isNotBlank(separate)) {
            newSeparate = separate;
        }
        int length = str.length();
        for (int i = 0; i < length; i++) {
            sb.append(Integer.toHexString(str.charAt(i) & 0xffff)).append(newSeparate);
        }
        if (sb.length() > 0) {
            int lastIndex = sb.lastIndexOf(newSeparate);
            sb.delete(lastIndex, sb.length());
        }
        return sb.toString();
    }

    /**
     * 判断中文字符
     *
     * @param c
     * @return
     */
    public static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS ||
                ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS ||
                ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A ||
                ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B ||
                ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION ||
                ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS ||
                ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否包含汉字（非标点符号）
     *
     * @param str
     * @return
     */
    public static boolean containsChinese(String str) {
        //[\u4E00-\u9FA5\\s]+ 多个汉字，包括空格
        //[\u4E00-\u9FA5]+ 多个汉字，不包括空格
        //[\u4E00-\u9FA5] 一个汉字
        //[^\x00-\xff]匹配双字节字符(包括汉字在内)：
        //Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Pattern pattern = Pattern.compile("^.*([\u4E00-\uFA29]|[\uE7C7-\uE7F3])+.*$");
        Matcher matcher = pattern.matcher(str);
        return matcher.find();
    }

    /**
     * 字符串转十六进制
     *
     * @param str
     * @return
     */
    public static String toHex(String str) {
        return toHex(str, null);
    }

    /**
     * 字符串转十六进制
     *
     * @param str
     * @param separate
     * @return
     */
    public static String toHex(String str, String separate) {
        byte[] bt = new byte[0];
        try {
            //GB2312标准共收录6763个汉字
            //GBK共收入包括21003个汉字和883个其它符号
            bt = str.getBytes("GBK");
        } catch (Exception e) {
            e.printStackTrace();
        }
        StringBuilder sb = new StringBuilder();
        String newSeparate = StringUtils.EMPTY;
        if (StringUtils.isNotBlank(separate)) {
            newSeparate = separate;
        }
        for (int i = 0; i < bt.length; i++) {
            String hexStr = Integer.toHexString(bt[i]);
            if (hexStr.length() > 2) {
                hexStr = hexStr.substring(hexStr.length() - 2);
            }
            sb.append(hexStr).append(newSeparate);
        }
        if (sb.length() > 0) {
            int lastIndex = sb.lastIndexOf(newSeparate);
            sb.delete(lastIndex, sb.length());
        }
        return sb.toString();
    }
}